#include "stl.h"
#include "ReadLine.hh"

#include "constants/chat.hh"
#include "tools/Color.hh"

ReadLine::ReadLine()
  : _currentInput(""),
    _currentInputIndex(0),
    _nbLineWraps(0),
    _highlighting(false),
    _command(false),
    _markPosition(0), // on Emacs: 'mark currently not set'
    _cursorPosition(0),
    _lineLength(CHAT_DEFAULT_LINE_LENGTH),
    _circularBufferIndex(0),
    //_circularBuffer,
    //_history(),
    _historyIndex(0),
    _cursorShape(CHAT_DEFAULT_CURSOR_SHAPE)
{
  // load aliases

  // build command list (=f(client / serv / admin / lvl / ...))

  // load history

    _cursorColor.setColor(COLOR_SOLID_WHITE);
    _currentFontColor.setColor(COLOR_SOLID_BLACK);
    _highlightColor.setColor(COLOR_SOLID_BLUE);
}


ReadLine::~ReadLine()
{
}


// __________ cursor motion
void ReadLine::moveCursorLeft()
{
  --_cursorPosition;
}

void ReadLine::moveCursorRight()
{
  ++_cursorPosition;
}

void ReadLine::moveCursorUp()
{
  _cursorPosition = std::max(_cursorPosition - _lineLength, 0);
}

void ReadLine::moveCursorDown()
{
  // we must cast _nbChars because of addition between the 2 unsigned chars
  _cursorPosition = std::min(_cursorPosition + _lineLength, (int) _nbChars);
}
// __________ end cursor motion


void ReadLine::addChar(char c)
{
  // add c, add autocompletion entries if needed

  if (c != '\n') // shd add a forbidden chars list ?
  {
    _currentInput[_currentInputIndex++] = c;
    return;
  }


  if (_nbLineWraps < CHAT_MAX_LINEWRAPS)
    _currentInput[_currentInputIndex++] = c;

//  if (_command)
    // autocompletion management

// also add '\n'
// on S-Enter (at most CHAT_MAX_LINEWRAPS)

}


void ReadLine::printEndOfInput()
{
  // blit a red sprite, blocked char size @ CHAT_MAX_ENTRY_LENGTH
}


void ReadLine::init()
{
  // clear _currentInput
  _command = false;
}


void ReadLine::clear()
{

}


// mouse 1 || 2 || C-c || C-d
bool ReadLine::interruptChat()
{
  bool keyInterrutPressed = false; // TODO fix this using glfweys

  return (keyInterrutPressed);
}


void ReadLine::cutCursorRight()
{
}


void ReadLine::highlightSelection()
{
}


void ReadLine::paste()
{
  _currentInput += _circularBuffer[_circularBufferIndex];
}


void ReadLine::copy()
{
  // zone between mark && cursor

  std::string zone;

//  zone.sub(1,43); // sumthin of this kind shd exist

  // _markPosition
    _circularBuffer[_circularBufferIndex++] = zone;
}


void ReadLine::cut()
{
  std::string str;

  //_circularBuffer[_circularBufferIndex] = // end of line
  // end of line <- '\0'

  if (_mark) // we're in selection mode
  {
    if (_mark == _cursorPosition) // 0 length str
      return;

    if (_mark < _cursorPosition)
      str = std::substr(_input, _mark, _cursorPosition);
    else
      str = std::substr(_input, _cursorPosition, _mark);
  }

  else // cut to the end mode
  {
    if (_cursorPosition >= _nbChars) // 0 length str || trouble
      return;

      str = std::substr(_input, _cursorPosition, _nbChars);
  }


  // check std::string auto-adding '\0'
  // if not: str += '\0';


  // adding cut text to the buffer
  _circularBufferLastEntry = ( 1 + _circularBufferLastEntry) % CHAT_DEFAULT_MAX_CIRCULAR_ENTRIES;
  _circularBuffer[_circularBufferLastEntry] = str;


  // remove cut text from _input
}


void ReadLine::circleThroughCircularBuffer()
{
}


void ReadLine::sendInput()
{
}


std::vector<std::string>* autoComplete()
{
  std::vector<std::string> completionList;

  if (!_command)
    return std::NULL; // cd add close po search // exists ?

  // browsing cmd list, 4 words beginning with _currentInput
  return &completionList;
}


void ReadLine::inChat()
{
  init();

  while (!interruptChat())
  {
    // get glfwKeyPressed

    if (_currentInput[0] == '/')
    {
      _fontType |= CHAT_FONT_BOLD;
      _command = true;
    }

    if (/* match key entry */)
    {
      sendInput();
      break;
    }
  }
}
